package com.binc.testspring.study.design.handler;

import lombok.Data;

import java.util.Objects;

/**
 * FileName: TestHandler   玩转责任链模式
 *
 *  关键点：
 *      抽象限一个责任链接口；然后后边有多个实现者，这些实现者在调用出设置一个执行链！！！（重要）；
 *      抽象类主要体重三个东西：
 *          1 当前的处理级别
 *          2 设置下一个处理者
 *          3 定义具体处理人的处理方法  (抽象，待子类实现)
 *          4 控制当前操作是否由当前处理人处理（final的，这个由父类控制，其实现仅仅负责具体的处理逻辑）
 *          5 为了保证高层代码的简单，我们在多创建一个client ，设置责任链的不走在client中设置，返回第一个责任链对象就行了；
 *
 * Autho: binC
 * Date:  2022/4/1 15:12
 */
public class TestHandler {

    public static void main(String[] args) throws Exception {
      /*  这里封装一个client   对高层代码更友好
        Handler p1 = new Person_1();
        Handler p2 = new Person_2();
        Handler p3 = new Person_3();
        p1.setNextHandler(p2);
        p2.setNextHandler(p3); //设置责任链，即  任务处理顺序 是 p1>p2>p3

        Request_binc request_binc = new Request_binc();
        request_binc.setRequest_levle("C"); // 设置当前请求的处理界别是3，就是level=C 的人去处理
        Response_binc response_binc = p1.handlerRequest(request_binc);
        System.out.println("======结束了");
*/
        HandlerClient hc = new HandlerClient();
        Handler first = hc.getProcessHandlers();
        Request_binc request_binc = new Request_binc();
        request_binc.setRequest_levle("C"); // 设置当前请求的处理界别是3，就是level=C 的人去处理
        Response_binc response_binc = first.handlerRequest(request_binc);
        System.out.println("----------结束了");
    }
}


// 定义个抽象责任链类
abstract class Handler{
    //0 为了防止level给出不符合要求的值，这里提前定义一些；（模板方法）  子类设置具体的level的时候，就只能用这里的值
    public final static String   LEVEL_A = "A";
    public final static String  LEVEL_B = "B";
    public final static String  LEVEL_C = "C";

    // 1 定义一个处理级别
    private String levle ;

    public Handler(String levle) {
        this.levle = levle;
    }

    //2 设置下一个处理者
    private Handler nextHandler;
    public void setNextHandler(Handler _handler) {
        this.nextHandler = _handler;
    }

    //3 子类真正的处理方法
    abstract Response_binc processRequest(Request_binc request);//

    //4 父类控制由谁真正处理
    //具体有哪个责任人处理当前任务是由父类控制的，这样子类只负责处理的真正逻辑，单一职责！！   注意用的是final  禁止子类重写 重载
   final Response_binc handlerRequest(Request_binc request) throws Exception {
        if (Objects.equals(this.levle, request.getRequest_levle())) {
            return this.processRequest(request);
        } else {
            if (this.nextHandler != null) {
                return this.nextHandler.handlerRequest(request);
            } else {
                throw new Exception("没有下一个责任人了，处理失败！ ");
            }
        }
    }
}

// 具体处理人1
class Person_1 extends  Handler {
    public Person_1() {
        super(Handler.LEVEL_A);//设置 person_1 的处理界别为A
    }

    @Override
    Response_binc processRequest(Request_binc request) {
        System.out.println("有person——1 处理当前任务");
        return new Response_binc();
    }
}

// 具体处理人2
class Person_2 extends  Handler {
    public Person_2() {
        super(Handler.LEVEL_B);//设置 person_2 的处理界别为B
    }

    @Override
    Response_binc processRequest(Request_binc request) {
        System.out.println("有person——2 处理当前任务");
        return new Response_binc();
    }
}

// 具体处理人3
class Person_3 extends  Handler {
    public Person_3() {
        super(Handler.LEVEL_C);//设置 Person_3 的处理界别为B
    }

    @Override
    Response_binc processRequest(Request_binc request) {
        System.out.println("有person——3 处理当前任务");
        return new Response_binc();
    }
}

// 5 封装客户端
class HandlerClient{
    //设置责任链，并返回责任链中第一个处理者
    Handler getProcessHandlers(){
        Handler p1 = new Person_1();
        Handler p2 = new Person_2();
        Handler p3 = new Person_3();
        p1.setNextHandler(p2);
        p2.setNextHandler(p3); //设置责任链，即  任务处理顺序 是 p1>p2>p3
        // 返回第一个处理者
        return p1;
    }
}


//请求参数实体
@Data
class Request_binc{
    private String request_levle; // 请求被处理的级别 最好是用枚举

}
//返回结果
class Response_binc{}
